import { _decorator, Component, AudioSource, AudioClip, Node } from 'cc';
import { BaseModule, IModule } from './base/BaseModule';
import { GameFramework } from './base/GameFramework';

const { ccclass } = _decorator;

/**
 * 音频类型枚举
 */
export enum AudioType {
    MUSIC = 'music',    // 背景音乐
    EFFECT = 'effect'   // 音效
}

/**
 * 音频系统，用于管理游戏中的音频播放
 */
@ccclass('AudioSystem')
export class AudioSystem extends BaseModule {

    // 音频源
    private _musicSource: AudioSource | null = null;
    private _effectSource: AudioSource | null = null;
    
    // 音频缓存
    private _audioCache: Map<string, AudioClip> = new Map();
    
    // 音量控制
    private _musicVolume: number = 1.0;
    private _effectVolume: number = 1.0;
    
    // 音频状态
    private _isMusicMuted: boolean = false;
    private _isEffectMuted: boolean = false;


    init(): void {
        // 创建音频源节点
        const musicNode = new Node('MusicSource');
        this._musicSource = musicNode.addComponent(AudioSource);
        GameFramework.instance.addChild(musicNode);
        
        const effectNode = new Node('EffectSource');
        this._effectSource = effectNode.addComponent(AudioSource);
        GameFramework.instance.addChild(effectNode);
        
        console.log("AudioSystem initialized");
    }

    shutdown(): void {
        // 停止所有音频
        this.stopMusic();
        this.stopAllEffects();
        
        // 清理缓存
        this._audioCache.clear();
        
        // 销毁音频源节点
        if (this._musicSource && this._musicSource.node) {
            this._musicSource.node.destroy();
        }
        
        if (this._effectSource && this._effectSource.node) {
            this._effectSource.node.destroy();
        }
        
        this._musicSource = null;
        this._effectSource = null;
        
        console.log("AudioSystem shutdown");
    }

    /**
     * 预加载音频资源
     * @param path 音频资源路径
     * @returns Promise<AudioClip>
     */
    async preloadAudio(path: string): Promise<AudioClip> {
        // 如果已经在缓存中，直接返回
        if (this._audioCache.has(path)) {
            return this._audioCache.get(path)!;
        }

        try {
            const clip = await GameFramework.resource.load<AudioClip>(path, AudioClip);
            this._audioCache.set(path, clip);
            return clip;
        } catch (error) {
            console.error(`Failed to preload audio: ${path}`, error);
            throw error;
        }
    }

    /**
     * 播放背景音乐
     * @param path 音频资源路径
     * @param loop 是否循环播放，默认true
     */
    async playMusic(path: string, loop: boolean = true): Promise<void> {
        if (!this._musicSource) {
            console.warn("Music source not initialized");
            return;
        }

        try {
            const clip = await this.preloadAudio(path);
            this._musicSource.clip = clip;
            this._musicSource.loop = loop;
            this._musicSource.volume = this._isMusicMuted ? 0 : this._musicVolume;
            this._musicSource.play();
        } catch (error) {
            console.error(`Failed to play music: ${path}`, error);
        }
    }

    /**
     * 停止背景音乐
     */
    stopMusic(): void {
        if (this._musicSource && this._musicSource.playing) {
            this._musicSource.stop();
        }
    }

    /**
     * 暂停背景音乐
     */
    pauseMusic(): void {
        if (this._musicSource && this._musicSource.playing) {
            this._musicSource.pause();
        }
    }

    /**
     * 恢复背景音乐
     */
    resumeMusic(): void {
        if (this._musicSource && !this._musicSource.playing) {
            this._musicSource.play();
        }
    }

    /**
     * 播放音效
     * @param path 音频资源路径
     * @param volume 音量（0-1）
     */
    async playEffect(path: string, volume: number = 1.0): Promise<void> {
        if (!this._effectSource) {
            console.warn("Effect source not initialized");
            return;
        }

        try {
            const clip = await this.preloadAudio(path);
            const actualVolume = this._isEffectMuted ? 0 : (volume * this._effectVolume);
            this._effectSource.playOneShot(clip, actualVolume);
        } catch (error) {
            console.error(`Failed to play effect: ${path}`, error);
        }
    }

    /**
     * 设置背景音乐音量
     * @param volume 音量（0-1）
     */
    setMusicVolume(volume: number): void {
        this._musicVolume = Math.max(0, Math.min(1, volume));
        if (this._musicSource && !this._isMusicMuted) {
            this._musicSource.volume = this._musicVolume;
        }
    }

    /**
     * 设置音效音量
     * @param volume 音量（0-1）
     */
    setEffectVolume(volume: number): void {
        this._effectVolume = Math.max(0, Math.min(1, volume));
    }

    /**
     * 静音/取消静音背景音乐
     * @param mute 是否静音
     */
    setMusicMute(mute: boolean): void {
        this._isMusicMuted = mute;
        if (this._musicSource) {
            this._musicSource.volume = mute ? 0 : this._musicVolume;
        }
    }

    /**
     * 静音/取消静音音效
     * @param mute 是否静音
     */
    setEffectMute(mute: boolean): void {
        this._isEffectMuted = mute;
    }

    /**
     * 停止所有音效
     */
    stopAllEffects(): void {
        // playOneShot播放的音效无法停止，这里只是提供接口
        console.warn("Cannot stop playOneShot effects. This is a limitation of Cocos Creator AudioSource.");
    }

    /**
     * 获取背景音乐是否正在播放
     */
    isMusicPlaying(): boolean {
        return this._musicSource ? this._musicSource.playing : false;
    }

    /**
     * 获取背景音乐是否暂停
     */
    isMusicPaused(): boolean {
        return this._musicSource ? !this._musicSource.playing : false;
    }
}